//一，什么是路由
路由就是一组key+value的对应关系
就是为了实现spa单页面跳转




//二，使用路由router
npm i vue-router@3  (router@4用在vue3中，router@3用在vue2中)

1) main.js文件中引入
//引入VueRouter
import VueRouter from "vue-router";
//引入路由器router
import router from "./router/index";

使用vue.use(VueRouter) //因为是插件，所以要使用就用vue.use()

// 创建vm
new Vue({
  el: "#app",
  render: (h) => h(App),
  router: router,
});

2)新建一个文件夹为router中新建一个index.js文件
//写入完整的路由
import VueRouter from "vue-router";

//引入组件
import About from "../pages/About";
import Home from "../pages/Home";

//定义一个路由并暴露出去
export default new VueRouter({
  routes: [
    {
      path: "/about",
      name: "about",
      component: About,
    },
    {
      path: "/home",
      name: "home",
      component: Home,
    }

3）再创建一个page文件夹About组件跟Home组件
在这两个组建中写自己想要的内容，这些用于跟组件
<router-link :to='/about'></router-link>

<router-view>用于将router-link中的文件渲染在router-view中</router-view>



//三，嵌套路由（多级路由）
比如在home中嵌套组件

1)在router中index.js中引入message组件
并在home组件下写入儿子
{
      path: "/home",
      name: "home",
      component: Home,
      children: [
        {
          path: "message",
          name: "message",
          component: Message,
          children: [
        },

2）创建一个message组件，然后在写入信息
<router-link :to='/home/message'></router-link>

<router-view>用于将router-link中的文件渲染在router-view中</router-view>





//四，路由传参（query,params两种传参）这两个用法是一样的，唯一不同的就是，params必须要在index.js中声明接收占位符，对象写法是不能用path，只能用name
1）query跟params写法
创建一个Detail组件，index.js引入，并在message中又来一个儿子
{
      path: "/home",
      name: "home",
      component: Home,
      children: [
        {
          path: "message",
          name: "message",
          component: Message,
          children: [
            {
              path: "detail/:id/:title", //要先声明params占位符(写在path中)
              name: "detail",
              component: Detail,
            },
          ],
        },

2）在detail中写入信息
并
<ul>
    <!-- query接收参数 -->
    <!-- <li>消息编号：{{$route.query.id}}</li>
    <li>消息标题：{{$route.query.title}}</li> -->

    <!-- params写法 -->
    <li>消息编号：{{$route.params.id}}</li>
    <li>消息标题：{{$route.params.title}}</li>
  </ul>
  mounted() {
    console.log(this.$route)
  }

3）在需要用在组件中也就是message组件中写入
<ul v-for="m in messageList" :key='m.id'>
      <li>
        <!-- to前面一定要加冒号，并且里面要加` ` -->
        <!-- query字符串写法 -->
        <!-- <router-link :to="`/home/Message/Detail?id=${m.id}&title=${m.title}`">{{m.title}}</router-link>&nbsp;&nbsp; -->

        <!-- query对象写法 要写path:'路径',query传参，path路径写的太长了（path:'/home/message/detail',），可以直接写name:'路径' -->
        <!-- <router-link :to="{
          name:'detail',
          query:{
            id:m.id,
            title:m.title,
          }
        }">{{m.title}}</router-link>&nbsp;&nbsp; -->

        <!-- params字符串写法 -->
        <!-- <router-link :to="`/home/message/detail/${m.id}/${m.title}`">{{m.title}}</router-link>&nbsp;&nbsp; -->
        <!-- params对象写法，必须用name配置，不能用path :to='{}' 大括号一定要挨着-->
        <router-link :to="{
          name:'detail',
          params:{
            id:m.id,
            title:m.title,
          }
        }
        ">{{m.title}}</router-link>&nbsp;&nbsp;
      </li>

    </ul>


//五，路由的props配置
让路由组件更方便的收到参数

{
      path: "/home",
      name: "home",
      component: Home,
      children: [
        {
          path: "message",
          name: "message",
          component: Message,
          children: [
            {
              path: "detail/:id/:title", //要先声明params占位符(写在path中)
              name: "detail",
              component: Detail,
              //第一种写法：props为对象，该对象中所有的key-value的都会以props形式传给detail组件,
              props:{
                a:'666',b:'999'
              }

              //第二种写法，props为布尔值，若布尔值为真，该路由所接收到的所有params参数通过props形式传给detail组件(query参数接收不到)
              props:true

              //第三种写法，props值为函数，该函数返回的对象中所有的key-value的都会以props形式传给detail组件,(回调函数，我们定义的，我们没调用，函数执行了)
              //可以用解构赋值的连续写法$route===》query====>query:{id,title}
              //id:$route.query.id====>query.id====>{id,title}
              props($route){
                return{
                  id:$route.query.id,
                  title:$route.query.title
                }
              }
            },
          ],
        },



detail接收
1)props:['a','b']





//六，route-link中的replace属性
浏览器有一个常用的历史记录，是一个栈结构，先进先出
push,还有replace(替换掉当前的站点的那一条)

replace属性：控制路由跳转时操作浏览器历史记录的模式
浏览器的历史记录有两种写入方式：push和replace，push是追加历史记录，replace是替换当前记录，路由跳转默认为push
如何开启replace模式：<router-link replace to='/'></router-link>
完整写法 :replace = 'true'



//七，编程式路由导航
不借助router-link导航，实现灵活跳转
push('路径'),replace('路径')，back()后退,forward()前进,go()传入数据，正数往前进，负数往后退

 <router-link :to="{
          name:'detail',
          params:{
            id:m.id,
            title:m.title,
          }
        }
        ">{{m.title}}</router-link>
        <button @click="pushshow(m)">push查看</button>
        <button @click="replaceshow(m)">replace查看</button>


 methods: {
    pushshow(m) {
      this.$router.push({
        name: 'detail',
        params: {
          id: m.id,
          title: m.title,
        }
      })
    },
    replaceshow(m) {
      this.$router.push({
        name: 'detail',
        params: {
          id: m.id,
          title: m.title,
        }
      })
    }
  }

//十，缓存路由组件
让不展示的路由组件保持挂载，不被销毁
只需要在对应的渲染组件中写一个标签
<keey-alive include='News'>
<router-view></router-view>
</keey-alive>

include='News'包含哪一个组件不被销毁的意思，里面的字符串是必须为组件名

<template>
  <div>
    <h2>Home组件内容</h2>
    <div>
      <ul class="nav nav-tabs">
        <li>
          <router-link class="list-group-item " active-class="active" to="/home/news">News</router-link>
        </li>
        <li>
          <router-link class="list-group-item " active-class="active" to="/home/message">Message</router-link>
        </li>
      </ul>
      <keep-alive include="News">
        <router-view></router-view>
      </keep-alive>

    </div>
  </div>
</template>